package com.galaxy.payment.utils;

import com.galaxy.common.core.exception.ServiceException;
import com.galaxy.common.json.utils.JsonUtils;
import com.galaxy.payment.api.RemoteOrderService;
import com.galaxy.payment.api.RemoteUserService;
import com.galaxy.payment.config.WxPayConfig;
import com.galaxy.payment.domain.OrderBo;
import com.galaxy.payment.domain.bo.AccountFlowBo;
import com.galaxy.payment.domain.bo.PaymentBo;
import com.galaxy.payment.domain.vo.PaymentRecordVo;
import com.galaxy.payment.service.IAccountFlowService;
import com.galaxy.payment.service.IPaymentRecordService;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;

/**
 * 微信支付工具类
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class WxPayUtils {

    private final WxPayConfig wxPayConfig;
    private final RSAAutoCertificateConfig rsaAutoCertificateConfig;
    private JsapiServiceExtension jsapiService;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private IPaymentRecordService paymentRecordService;


    @Autowired
    private IAccountFlowService iAccountFlowService;

    @Autowired
    private RemoteOrderService remoteOrderService;

    /**
     * 获取JSAPI支付服务
     */
    public JsapiServiceExtension getJsapiService() {
        if (jsapiService == null) {
            try {
                jsapiService = new JsapiServiceExtension.Builder()
                    .config(rsaAutoCertificateConfig)
                    .build();
                log.info("微信支付JSAPI服务初始化成功");
            } catch (Exception e) {
                log.error("创建微信支付JSAPI服务失败: {}", e.getMessage(), e);
                throw new ServiceException("创建微信支付JSAPI服务失败: " + e.getMessage());
            }
        }
        return jsapiService;
    }

    /**
     * 创建JSAPI支付订单
     */
    /**
     * 创建JSAPI支付订单
     */
    public PrepayWithRequestPaymentResponse createJsapiPayment(String orderNo, String description,
                                                               BigDecimal amount, String openid,String type) {
        try {
            // 先查询订单状态
            Transaction transaction = queryOrderStatus(orderNo);
            if (transaction != null && transaction.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)) {
                // 订单已支付，直接返回成功
                log.info("订单已支付，订单号: {}", orderNo);
                PaymentRecordVo paymentRecord = paymentRecordService.getPaymentRecordByOrderNo(orderNo);
//                updateOrderStatus(orderNo, "PAID"); // 假设有一个方法用于更新订单状态
                AccountFlowBo accountFlowBo = new AccountFlowBo();
                accountFlowBo.setUserId(paymentRecord.getUserId());
                accountFlowBo.setOrderNo(orderNo);
                accountFlowBo.setFlowType(Objects.equals(type, "充值") ? 1 : 2);
                accountFlowBo.setAmount(Objects.equals(type, "充值")?paymentRecord.getPaymentAmount():paymentRecord.getPaymentAmount().negate());

                accountFlowBo.setBalance(BigDecimal.ZERO);
                accountFlowBo.setDescription(Objects.equals(type, "充值") ? "充值余额" : "微信支付购买商品");
                iAccountFlowService.insertByBo(accountFlowBo);


                PaymentBo updateBo = new PaymentBo();
                updateBo.setPayNo(paymentRecord.getPayNo());
                updateBo.setStatus(2); // 支付成功
                updateBo.setSuccessTime(new Date());
                updateBo.setId(paymentRecord.getId());
                paymentRecordService.updateByBo(updateBo);
                OrderBo orderBo =  new OrderBo();
                orderBo.setId(paymentRecord.getOrderId());
                orderBo.setPayType(1);
                orderBo.setStatus(2);
                orderBo.setOutTradeNo(paymentRecord.getPayNo());
                orderBo.setPayTime(LocalDateTime.now());
                orderBo.setCompleteTime(LocalDateTime.now());
                remoteOrderService.edit(orderBo);

                return null; // 或者返回一个表示已支付的对象
            }

            // 创建预支付请求
            PrepayRequest request = new PrepayRequest();

            // 设置金额
            Amount amountObj = new Amount();
            amountObj.setTotal(1);
            request.setAmount(amountObj);

            // 设置基本信息
            request.setAppid(wxPayConfig.getAppid());
            request.setMchid(wxPayConfig.getMerchantId());
            request.setDescription(description);
            request.setNotifyUrl(wxPayConfig.getNotifyUrl());
            request.setOutTradeNo(orderNo);

            // 设置支付者信息
            Payer payer = new Payer();
            payer.setOpenid(openid);
            request.setPayer(payer);

            PrepayWithRequestPaymentResponse prepayWithRequestPaymentResponse = getJsapiService().prepayWithRequestPayment(request);

            // 发起支付
            return prepayWithRequestPaymentResponse;
        } catch (Exception e) {
            log.error("创建微信支付订单失败: {}", e.getMessage(), e);
            throw new ServiceException("创建微信支付订单失败: " + e.getMessage());
        }
    }

    /**
     * 查询订单状态
     */
    public Transaction queryOrderStatus(String orderNo) {
        try {
            QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
            queryRequest.setMchid(wxPayConfig.getMerchantId());
            queryRequest.setOutTradeNo(orderNo);
            return getJsapiService().queryOrderByOutTradeNo(queryRequest);
        } catch (Exception e) {
            log.error("查询微信支付订单状态失败: {}", e.getMessage(), e);
            return null;
        }
    }


    /**
     * 根据用户ID获取openid
     */
    public String getOpenidByUserId(Long userId) {
        return remoteUserService.getOpenid(userId).getData();
    }
}
